<?php
/**
 * Hesperos library for Zend Framework
 *
 * This script is protected by copyright. It's use, copying, modification
 * and distribution without written consent of the author is prohibited.
 *
 * @category    Hesperos
 * @package     Util
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @license     http://www.gnu.org/licenses/lgpl-3.0.txt  GNU Lesser General Public
 * @version     1.0 $Id$
 * @link        http://code.google.com/p/hesperos/
 */

/**
 * Narzędzia, czytnik danych ACL
 *
 * @category    Hesperos
 * @package     Util
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @version     1.0 $Id$
 */
class Hesperos_Util_Reader_Acl
{
    /**
     * Tablica zasobów
     *
     * @var array
     */
    private $_resources = array();

    /**
     * Tablica dostępów
     *
     * @var array
     */
    private $_allow = array();

    /**
     * Tablica ograniczeń dostępów
     *
     * @var array
     */
    private $_deny = array();

    /**
     * Stałe
     */
    const RESOURCES = 'resources';
    const ALLOW = 'allow';
    const DENY = 'deny';
    const RESOURCE  = 'resource';
    const ROLE  = 'role';
    const PRIVILEGE  = 'privilege';

    /**
     * Konstruktor
     *
     * @param string $xml dane xml
     */
    public function __construct($xml)
    {
        $this->_read(new SimpleXMLElement ($xml));
    }

    /**
     * Odczyt reguł (resources, allow, deny)
     *
     * @param string SimpleXMLElement $xml obiekt klasy SimpleXMLElement
     */
    private function _read (SimpleXMLElement $xml)
    {
        foreach ($xml->children() as $name => $element) {
            if($name == self::RESOURCES) {
                $this->_readResource($element);
            } else if ($name == self::ALLOW) {
                $this->_readAllow($element);
            } else if ($name == self::DENY) {
                $this->_readDeny($element);
            }
        }
    }

    /**
     * Odczyt reguł resource
     *
     * @param string SimpleXMLElement $xml obiekt klasy SimpleXMLElement
     */
    private function _readResource (SimpleXMLElement $xml)
    {
        foreach($xml->children() as $name => $element) {
            if($name == self::RESOURCE && isset($element['name'])) {
                $resource = array('resource' => (string)$element['name']);
                if(isset($element['parent'])) {
                    $resource['parent'] = (string)$element['parent'];
                }
                $this->_resources[] = $resource;
            }
        }
    }

    /**
     * Odczyt reguł allow
     *
     * @param string SimpleXMLElement $xml obiekt klasy SimpleXMLElement
     */
    private function _readAllow (SimpleXMLElement $xml)
    {
        foreach($xml->children() as $name => $element) {
            if($name == self::ROLE && isset($element['name'])) {
                $role = array('role' => (string)$element['name'], 'resources' => array());

                foreach($element->children() as $res => $resData) {
                    if($res == self::RESOURCE && isset($resData['name'])) {
                        $resource = array('resource' => (string)$resData['name'], 'privileges' => array());
                    }

                    foreach($resData->children() as $priv => $privData) {
                        if($priv == self::PRIVILEGE && isset($privData['name'])) {
                            $resource['privileges'][] = (string)$privData['name'];
                        }
                    }
                    $role['resources'][] = $resource;
                }

                $this->_allow[] = $role;
            }
        }
    }

    /**
     * Odczyt reguł deny
     *
     * @param string SimpleXMLElement $xml obiekt klasy SimpleXMLElement
     */
    private function _readDeny (SimpleXMLElement $xml)
    {
        foreach($xml->children() as $name => $element) {
            if($name == self::ROLE && isset($element['name'])) {
                $role = array('role' => (string)$element['name'], 'resources' => array());

                foreach($element->children() as $res => $resData) {
                    if($res == self::RESOURCE && isset($resData['name'])) {
                        $resource = array('resource' => (string)$resData['name'], 'privileges' => array());
                    }
                    foreach($resData->children() as $priv => $privData) {
                        if($priv == self::PRIVILEGE && isset($privData['name'])) {
                            $resource['privileges'][] = (string)$privData['name'];
                        }
                    }
                    $role['resources'][] = $resource;
                }

                $this->_deny[] = $role;
            }
        }
    }

    /**
     * Zwraca tablicę zasobów
     *
     * @param array
     */
    public function getResources ()
    {
        return $this->_resources;
    }

    /**
     * Zwraca tablicę konfiguracji dostępu
     *
     * @param array
     */
    public function getAllow ()
    {
        return $this->_allow;
    }

    /**
     * Zwraca tablicę konfiguracji ograniczeń dostępu
     *
     * @param array
     */
    public function getDeny ()
    {
        return $this->_deny;
    }
}